import time
import urllib.parse
import zipfile
import os
import random
import string
import json
import requests
from obs import ObsClient

localMountPath = '/tmp/'


def handler(event, context):
    ak = context.getAccessKey()
    sk = context.getSecretKey()
    if ak == "" or sk == "":
        context.getLogger().log('Failed to access OBS because no temporary '
                                'AK, SK, or token has been obtained. Please '
                                'set an agency.')
        return 'Failed to access OBS because no temporary AK, SK, or token ' \
               'has been obtained. Please set an agency. '

    logger = context.getLogger()

    records = event.get("Records", None)
    (src_bucket, input_object_key) = get_obs_obj_info(records[0])
    logger.info("src bucket name: %s", src_bucket)

    input_object_key = urllib.parse.unquote(input_object_key)
    logger.info("src object key: %s", input_object_key)

    download_path = context.getUserData("downloadPath", default='')
    download_dir = gen_local_download_path(download_path)

    obs_endpoint = context.getUserData('obs_endpoint')
    obs_client = new_obs_client(context, obs_endpoint)

    # Downloads the src object key from OBS to a local directory.
    if not download_from_obs(context, obs_client, src_bucket, input_object_key, download_dir):
        return 'ERROR'

    extract_dir = download_dir + '/ext/'
    download_file = download_dir + input_object_key
    extract_files(download_file, extract_dir)

    auth_token = context.getToken()
    project_id = context.getProjectID()
    log_group_id = context.getUserData("log_group_id")
    log_stream_id = context.getUserData("log_stream_id")
    lts_ip = context.getUserData("lts_ip")

    url = lts_ip + '/v2/' + project_id + '/lts/groups/' + log_group_id + '/streams/' + log_stream_id + '/tenant/contents'
    headers = {'content-type': 'application/json', 'X-Auth-Token': auth_token}
    pathDir = os.listdir(extract_dir)
    for allDir in pathDir:
        child = os.path.join('%s%s' % (extract_dir, allDir))
        (filename, ext) = os.path.splitext(child)
        if ext != '.log':
            continue
        f = open(child)
        lines = f.readlines()
        for line in lines:
            logger.info(line)
            payload = {"log_time_ns": int(round(time.time() * 1000000000)), "contents": line, "labels": {"user_tag": "string"}}
            response = requests.post(url, data=json.dumps(payload), headers=headers, verify=False).text
            # context.getLogger.info(response)
            logger.info(response)

    os.remove(download_file)
    return 'SUCCESS'


def extract_files(download_file, extract_dir):
    zFlie = zipfile.ZipFile(download_file, "r")
    for file in zFlie.namelist():
        zFlie.extract(file, extract_dir)
    zFlie.close()


def download_from_obs(context, obs_client, bucket, object_key, download_dir):
    resp = obs_client.getObject(bucket, object_key, downloadPath=download_dir + object_key)
    if resp.status < 300:
        return True
    else:
        context.getLogger().error('failed to download_from_obs '
                                  'errorCode: %s, errorMessage: %s' % (
                                      resp.errorCode, resp.errorMessage))
        return False


# generate a temporary directory for downloading things
# from OBS and compress them.
def gen_local_download_path(download_path):
    if len(download_path) == 0:
        download_path = localMountPath

    if not download_path.endswith('/'):
        download_path += '/'

    letters = string.ascii_letters
    download_dir = download_path + ''.join(
        random.choice(letters) for i in range(16)) + '/'
    os.makedirs(download_dir)
    return download_dir


def new_obs_client(context, obsServer):
    ak = context.getAccessKey()
    sk = context.getSecretKey()
    return ObsClient(access_key_id=ak, secret_access_key=sk, server=obsServer)


def get_obs_obj_info(record):
    s3 = record['s3']
    return (s3['bucket']['name'], s3['object']['key'])